package com.miyu.common.utils.aop;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.miyu.common.utils.taskJob.RedisTaskCahe;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 做日志处理
 * 调用接口记录
 * 记录内容
 * dateApi 操作时间
 * logParam 传入参数
 * cosApi 接口调用
 * method 调用类型
 * beginTime 调用接口开始时间
 * endTime 接口调用结束时间
 * className 调用接口名称
 * data 返回接口
 *
 */
public class CosLog {
    public static void cosLog(ProceedingJoinPoint joinPoint, Object proceed, String beginTime, String endTime){
        //获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        //如果要获取Session信息的话，可以这样写：
        HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 请求的方法参数值
        Object[] args = joinPoint.getArgs();
        // 请求的方法参数名称
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        String params = "";
        if (args != null && paramNames != null) {
            for (int i = 0; i < args.length; i++) {
//                System.out.println(i+" paramNames[i]="+paramNames[i]+",args[i]="+args[i]);
                params += args[i];
            }
        }
        // 设置IP地址
        String ip = getIpAddr(request);
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        String type = request.getMethod();//POST/GET
        //查询返回值
//        System.out.println("ip = "+ip);
//        System.out.println("className = "+className);
//        System.out.println("methodName = "+methodName);
//        System.out.println("type = "+type);
//        System.out.println("target=" + joinPoint.getTarget());
//        System.out.println("kind=" + joinPoint.getKind());
//        System.out.println("proceed=" + proceed.toString());  //返回结果

        JSONObject data = new JSONObject();
        data.put("code","200");
        data.put("msg","OK");
        data.put("data",proceed);
        JSONObject log = new JSONObject();
        log.put("dateApi", DateUtil.now());//操作时间
        log.put("logIp",ip);//操作IP
        log.put("logParam",params);//传入参数
        log.put("cosApi",methodName);//接口调用
        log.put("method",type);//调用类型
        log.put("beginTime",beginTime);//调用接口开始时间
        log.put("endTime",endTime);//接口调用结束时间
        log.put("className",className);//调用接口名称
        //log.put("data",data);//由于数据量查询过大 暂时不缓存返回数据
        // 判断是否登录
        if(StpUtil.isLogin()){
            log.put("loginUser",StpUtil.getLoginId());//登录账户
            log.put("loginType",StpUtil.getLoginDevice());//登录类型
        }
        //判断所在包位置 暂时只存储system 程序数据
        if(className.indexOf("com.miyu.system")>-1){
            ExecutorService exec = Executors.newCachedThreadPool();
            exec.submit(new RedisTaskCahe(1,1,"cosApiLog",log));
        }
    }
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if(ip!=null|| ip.length() >0){
            String[]  ipStr =ip.split(",");
            ip=ipStr[0];
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
